package com.limm.myapplication.viewmodel;

import android.app.Application;
import android.media.MediaPlayer;
import android.util.Log;
import android.util.Pair;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.limm.myapplication.view.MyMediaPlay;
import com.limm.myapplication.vo.PlayStatus;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PlayerViewModel extends AndroidViewModel implements MediaPlayer.OnVideoSizeChangedListener,
        MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {

    private static final String videoPath = "https://outin-7478cf551c4811ecaef900163e12ac16.oss-cn-shenzhen.aliyuncs.com/customerTrans/1196025d2d265b43e896c1dbb804e079/40cb5016-17c2b245c12-0003-ebd2-f44-2066e.mp4?Expires=1639023992&OSSAccessKeyId=LTAI4FocoL6tuCdYhuvug6Ee&Signature=fJogetTDJYBCBmtPPoM4Au11vYY%3D";


    private long controllerShowTime = 0L;
    public MyMediaPlay mediaPlayer = new MyMediaPlay();
    private MutableLiveData<Integer> progressBarVisibility = new MutableLiveData<>();
    private MutableLiveData<Integer> controllerFrameVisibility = new MutableLiveData<>();
    private MutableLiveData<PlayStatus> playStatus = new MutableLiveData<>();
    private MutableLiveData<Integer> bufferPercent = new MutableLiveData<>();
    private MutableLiveData<Pair<Integer, Integer>> videoResolution = new MutableLiveData<>();
    public final ExecutorService executors = Executors.newSingleThreadExecutor();


//    private static final String videoPath = "rtsp://admin:Admin123@10.8.rtsp://admin:Admin123@58.20.230.32:10061/Streaming/Channels/201\n";

    public PlayerViewModel(@NonNull Application application) throws IOException {
        super(application);
        loadVideo();
//        Log.e("prepareAsync", mediaPlayer.isLooping() + "");
//        Log.e("prepareAsync", mediaPlayer.isPlaying() + "");
        Log.e("prepareAsync", mediaPlayer.isLooping() + "");
        Log.e("prepareAsync", mediaPlayer.isPlaying() + "");
    }


    public LiveData<Integer> getProgressBarVisibility() {
        return progressBarVisibility;
    }

    public LiveData<Pair<Integer, Integer>> getVideoResolution() {
        return videoResolution;
    }

    public LiveData<Integer> getControllerFrameVisibility() {
        return controllerFrameVisibility;
    }

    public LiveData<Integer> getBufferPercent() {
        return bufferPercent;
    }

    public LiveData<PlayStatus> getPlayStatus() {
        return playStatus;
    }


    public void loadVideo() throws IOException {

        progressBarVisibility.postValue(View.VISIBLE);
        controllerFrameVisibility.postValue(View.VISIBLE);
        playStatus.postValue(PlayStatus.NoReady);
        mediaPlayer.reset();

        mediaPlayer.setDataSource(videoPath);
        mediaPlayer.setOnBufferingUpdateListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnVideoSizeChangedListener(this);
        mediaPlayer.setOnErrorListener(this);

        mediaPlayer.reset();
        mediaPlayer.setDataSource(videoPath);

        mediaPlayer.setOnPreparedListener(mp -> {
            progressBarVisibility.postValue(View.INVISIBLE);
//            mp.setLooping(true);
            mp.start();
            playStatus.postValue(PlayStatus.Playing);
        });

        mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
            @Override
            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                videoResolution.postValue(new Pair<>(width, height));
            }
        });


        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
//                mp.stop();
                Log.e("setOnErrorListener:: ", "in");
                mp.reset();
                return true;
            }
        });

        mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(MediaPlayer mp) {
                mediaPlayer.start();
                progressBarVisibility.postValue(View.INVISIBLE);
            }
        });

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                playStatus.postValue(PlayStatus.Completed);
            }
        });
        mediaPlayer.prepare();
//        try {
//            Thread.sleep(3000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }

    public void emmitVideoResolution() {
        videoResolution.postValue(videoResolution.getValue());
    }

    public void toggleControllerVisibility() {
        if (controllerFrameVisibility.getValue() == View.INVISIBLE) {
            controllerFrameVisibility.postValue(View.VISIBLE);
            controllerShowTime = System.currentTimeMillis();
            executors.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(2000);
                        if (System.currentTimeMillis() - controllerShowTime > 2000) {
                            controllerFrameVisibility.postValue(View.INVISIBLE);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        } else {
            controllerFrameVisibility.postValue(View.INVISIBLE);
        }

    }

    public void playSeekToProgress(int progress) {
        progressBarVisibility.postValue(View.VISIBLE);
        mediaPlayer.seekTo(progress);
        if (playStatus.getValue() == PlayStatus.Paused) {
            playStatus.postValue(PlayStatus.Playing);
        }
    }

    public void togglePlayerStatus() {
        switch (playStatus.getValue()) {
            case Playing: {
                mediaPlayer.pause();
                playStatus.postValue(PlayStatus.Paused);
                break;
            }
            case Paused:
            case Completed: {
                mediaPlayer.start();
                playStatus.postValue(PlayStatus.Playing);
                break;
            }
            default: {
                break;
            }

        }
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        mediaPlayer.release();
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        bufferPercent.postValue(percent);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        progressBarVisibility.postValue(View.INVISIBLE);
        mp.setLooping(true);
        mp.start();
    }


    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        videoResolution.postValue(new Pair<>(width, height));
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        //                mp.stop();
        Log.e("setOnErrorListener:: ", "in");
        mp.reset();
        return true;
    }


}
